package taboo

import (
	"regexp"
	"strings"
)

// MatchReg 正则匹配2
type MatchReg struct {
	regs  []*regexp.Regexp
	words []string
	exps  []string
}

// NewReg 构造一个正则匹配
func NewReg(words []string) *MatchReg {
	mr := &MatchReg{
		words: words,
	}
	builder := strings.Builder{}
	for _, w := range words {
		w = strings.ToLower(strings.TrimSpace(w))
		v := []rune(w)
		builder.Reset()
		for i, r := range v {
			builder.WriteString(regexp.QuoteMeta(string(r)))
			if i < len(v)-1 {
				builder.WriteString(`.{0,3}`)
			}
		}
		exp := builder.String()
		mr.words = append(mr.words, w)
		mr.exps = append(mr.exps, exp)
		mr.regs = append(mr.regs, regexp.MustCompile(exp))
	}
	return mr
}

// Contains 是否包含
func (mr *MatchReg) Contains(text string) bool {
	matches := mr.Find(text)
	return len(matches) > 0
}

// Find 找到一个匹配
func (mr *MatchReg) Find(text string) []Match {
	text = strings.ToLower(strings.TrimSpace(text))
	for i, reg := range mr.regs {
		loc := reg.FindStringIndex(text)
		if len(loc) == 0 {
			continue
		}
		var matches []Match
		matches = append(matches, Match{
			Start:  loc[0],
			End:    loc[1],
			Word:   mr.words[i],
			Fuzzy:  true,
			RegExp: mr.exps[i],
		})
		return matches
	}
	return nil
}

// FindAll 查找全部
func (mr *MatchReg) FindAll(text string) []Match {
	text = strings.ToLower(strings.TrimSpace(text))
	var matches []Match
	for i, reg := range mr.regs {
		locs := reg.FindAllStringIndex(text, -1)
		for _, loc := range locs {
			matches = append(matches, Match{
				Start:  loc[0],
				End:    loc[1],
				Word:   mr.words[i],
				Fuzzy:  true,
				RegExp: mr.exps[i],
			})
		}
	}
	return matches
}

// ReplaceAll 全部替换
func (mr *MatchReg) ReplaceAll(text, repl string) string {
	text = strings.ToLower(strings.TrimSpace(text))
	for _, reg := range mr.regs {
		text = reg.ReplaceAllStringFunc(text, func(s string) string {
			v := []rune(s)
			r := []rune(repl)
			for i := range v {
				v[i] = r[i%len(r)]
			}
			return string(v)
		})
	}
	return text
}
